package com.lhd.dbpool;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 类 {@code PoolUtil2} 数据库连接池工具2.
 *
 * <p>主要包括 初始化连接池、关闭连接、释放连接等功能，从配置文件config/dbcp.prop读取数据库连接信息
 *
 * @author MapLover
 * @since 2020.09
 */
@Slf4j
public class PoolUtil {
    // 数据库连接池需实现javax.sql.DataSource接口，DBCP连接池是javax.sql.DataSource接口的具体实现
    private static  BasicDataSource dataSource = new BasicDataSource();

    private static final Properties properties = new Properties();


    // 使用静态代码块创建数据库连接池
    static {
        try {
            dataSourceConfig();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 加载DBCP配置文件
    private static void dataSourceConfig() throws IOException,NullPointerException {
        log.info("---1.init data source pool----------");

        try (FileInputStream fis = new FileInputStream("conf/dbcp.prop")) {
            properties.load(fis);

            log.info("---2.Load prop: " + properties.getProperty("url"));


        } catch (IOException e) {
            log.error(e.getMessage());
        }

        try {
            dataSource = BasicDataSourceFactory.createDataSource(properties);
            log.info("---3.Create DataSourceConfig OK-----");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * @return 一个数据库连接
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            log.info(Thread.currentThread().getName()+"--Get A Connection:"+conn.getMetaData().getDatabaseProductName()+"-"+conn.getMetaData().getDatabaseProductVersion());

        } catch (SQLException e) {
            log.error(e.getMessage());
        }

        return conn;
    }

    /**
     * @param conn 当前连接Connection
     * @param st   当前statement
     * @param rs   当前ResultSet
     */
    public static void release(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                // 关闭存储查询结果的ResultSet对象
                rs.close();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }

        if (st != null) {
            try {
                st.close();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }

        if (conn != null) {
            try {
                // 将Connection连接对象还给数据库连接池
                conn.close();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }


    public static void main(String[] args) {
        for (int i=1;i<=3;i++){
            log.info(String.valueOf(i));
            PoolUtil.getConnection();
        }
    }
}
